package com.nami.ucenter.domain.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.nami.gate.external.basic.cache.user.UserDeviceRel;
import com.nami.gate.external.basic.constants.DownTopicConst;
import com.nami.im.network.model.enums.DownMsgErrorCode;
import com.nami.transport.proto.codec.DownWsMsg;
import com.nami.transport.proto.codec.MqTransMsg;
import com.nami.ucenter.domain.convertor.UserConvert;
import com.nami.ucenter.domain.model.UserLoginModel;
import com.nami.ucenter.domain.model.UserModel;
import com.nami.ucenter.domain.port.publisher.DomainEventPublisher;
import com.nami.ucenter.domain.port.repository.PacketFactory;
import com.nami.ucenter.domain.port.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SessionUtil;
import org.dromara.common.redis.utils.RedisTemplateKit;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.nami.gate.external.basic.constants.CommonConst.COLON;
import static org.dromara.common.core.constant.RedisConst.CACHE_PREFIX;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserLoginDomainService {

    private final UserRepository userRepository;
    private final DomainEventPublisher eventPublisher;
    private final RedisTemplateKit redisTemplateKit;
    private final PacketFactory packetFactory;

    @Deprecated
    public Map<String, UserModel> getUsersByIds(List<String> userIds) {
        List<UserModel> list = userRepository.listByUserIds(userIds);
        if (CollUtil.isEmpty(userIds)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(UserModel::getUserId, Function.identity()));
    }

    public boolean register(UserModel user) {
        UserModel userByMobile = userRepository.getUserByMobile(user.getMobile());
        if (userByMobile != null) {
            throw new ServiceException("用户已注册！");
        }

        user.setUserType(10);
        user.setStatus(10);
        user.setUserId(IdUtil.getSnowflakeNextId() + "");
        user.setSalt(RandomUtil.randomString(6));
        userRepository.add(user);
        return Boolean.TRUE;
    }

    public UserDeviceRel getOnlUser(String appKey, String userId) {
        UserDeviceRel userWrap = (UserDeviceRel) redisTemplateKit.hget(buildOnlineUserKey(appKey), userId);
        return UserConvert.INSTANCE.convert3(userWrap);
    }

    private static String buildOnlineUserKey(String appKey) {
        return CACHE_PREFIX + appKey + COLON + "user:info";
    }

    public void publishLoginSuccEvent(UserLoginModel model) {
        String sessionId = SessionUtil.binding(model.getUserId(), model.getInstanceId());

        DownWsMsg.ConnectAckMsgBody downMsg = DownWsMsg.ConnectAckMsgBody.newBuilder()
            .setCode(DownMsgErrorCode.SUCCESS.getCode())
            .setUserId(model.getUserId())
            .setTimestamp(System.currentTimeMillis())
            .build();

        MqTransMsg.Logic2GateLoginResponse transLoginBody = MqTransMsg.Logic2GateLoginResponse.newBuilder()
            .setSuccess(Boolean.TRUE)
            .setTempFingerprint(model.getTempFingerprint())
            .setUserId(model.getUserId())
            .setSessionId(sessionId)
            .setInstanceId(model.getInstanceId())
            .setAppKey(model.getAppKey())
            .setPlatform(model.getPlatform())
            .setDownMsgBody(downMsg)
            .build();

        eventPublisher.publish(DownTopicConst.LOGIN_TOPIC, model.getConnectId(), transLoginBody.toByteArray());
    }

    public void sendLoginFailureResponse(String userId,
                                         String fingerprint,
                                         String connectId,
                                         DownMsgErrorCode errorCode) {
//        ClientResponse clientResponse = ClientResponse.buildFailure(errorCode.getCode(), errorCode.getMsg());
//
//        DownLoginWrap resp = new DownLoginWrap();
//        resp.setSuccess(Boolean.FALSE);
//        resp.setPacket(createResponsePacket(clientResponse));
//        resp.setTempFingerprint(fingerprint);

        DownWsMsg.ConnectAckMsgBody downMsg = DownWsMsg.ConnectAckMsgBody.newBuilder()
            .setCode(errorCode.getCode())
            .setUserId(userId)
            .setTimestamp(System.currentTimeMillis())
//            .setSession()
            .build();

        MqTransMsg.Logic2GateLoginResponse transLoginBody = MqTransMsg.Logic2GateLoginResponse.newBuilder()
            .setSuccess(Boolean.FALSE)
            .setTempFingerprint(fingerprint)
            .setDownMsgBody(downMsg)
            .build();
        eventPublisher.publish(DownTopicConst.LOGIN_TOPIC, connectId, transLoginBody.toByteArray());
    }

    public boolean fillParamsAfterCheck(UserLoginModel model) {
        // 获取用户信息
        UserModel userInfo = userRepository.find(model.getAppKey(), model.getUserId());
        if (Objects.isNull(userInfo)) {
            this.sendLoginFailureResponse(model.getUserId(),
                model.getTempFingerprint(),
                model.getConnectId(), DownMsgErrorCode.FROM_USER_NOT_EXIST);
            return Boolean.TRUE;
        }
        model.setNick(userInfo.getNickname());
        model.setAvatar(userInfo.getAvatarUrl());
        model.setStatus(userInfo.getStatus());
        return Boolean.FALSE;
    }
}
